package com.ef.web.action;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.write.BorderLineStyle;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

import org.apache.struts2.ServletActionContext;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import com.ef.constant.ConfirmMessage;
import com.ef.constant.EContractState;
import com.ef.constant.StatusType;
import com.ef.domain.CorpClass;
import com.ef.domain.CorpContract;
import com.ef.domain.CorpPayHistory;
import com.ef.service.CompanyService;
import com.ef.service.CorpClassService;
import com.ef.service.CorpContractService;
import com.ef.service.CorpPayService;
import com.ef.util.CustomExample;

public class CorpContractAction extends BaseAction<CorpContract> {

	private static final long serialVersionUID = 1L;

	private CorpContractService corpContractService;

	private CompanyService companyService;

	private CorpClassService corpClassService;

	private String selCompanyId;

	private List<CorpPayHistory> corpPayHistoryList;

	private List<CorpClass> corpClassList;

	private CorpPayService corpPayService;

	private String selCompanyName;

	private Date selCreateStartTime;

	private Date selCreateEndTime;

	private Date selCommitStartTime;

	private Date selCommitEndTime;

	private Date selFinishStartTime;

	private Date selFinishEndTime;

	private Date selBeginStartTime;

	private Date selBeginEndTime;

	private Date selEndStartTime;

	private Date selEndEndTime;

	@SuppressWarnings("serial")
	public String list() {
		this.listResult = corpContractService.findByExample(
				new CustomExample<CorpContract>(this.getModel()) {
					public void appendCondition(Criteria criteria) {
						if ((selCompanyName != null && selCompanyName.trim()
								.length() > 0)) {
							criteria.createAlias("company", "company");
							criteria.add(Restrictions
											.like("company.name",
													selCompanyName.trim(),
													MatchMode.ANYWHERE));

						}
						criteria.add(Restrictions
								.eq("status", StatusType.VALID));
						this.addBetweenDateProperty("createTime",
								selCreateStartTime, selCreateEndTime);
						this.addBetweenDateProperty("commitTime",
								selCommitStartTime, selCommitEndTime);
						this.addBetweenDateProperty("finishTime",
								selFinishStartTime, selFinishEndTime);
						this.addBetweenDateProperty("startTime",
								selBeginStartTime, selBeginEndTime);
						this.addBetweenDateProperty("endTime", selEndStartTime,
								selEndEndTime);
						appendBetweenDateProperty(criteria);
						this.enableLike(MatchMode.ANYWHERE);
					}
				}, this.getStartIndex(), this.getPageSize());
		return LIST;
	}

	public boolean canInvalidOrFinish() {
		if (this.getModel().getContractState() != null) {
			return getModel().getContractState().equals(EContractState.COMMIT);
		}
		return false;
	}

	private void fetchListData() {
		if (this.getModel().getId() != null
				&& this.getModel().getCompany() != null) {
			this.selCompanyId = this.getModel().getCompany().getId().toString();
		}

		if (this.getModel().getId() != null) {
			corpPayHistoryList = corpPayService.findByContract(this.getModel());
			corpClassList = corpClassService.findByContract(this.getModel());
		}
	}

	public String redirect() {
		fetchListData();
		if (this.getModel().getContractState().equals(EContractState.NEW)) {
			return EDIT;
		} else {
			return VIEW;
		}
	};

	public String edit() {
		fetchListData();
		return EDIT;
	};

	public String finish() {
		StringBuffer respon = new StringBuffer();
		CorpContract cont = this.getModel();
		if (cont.getContractState() != null) {
			if (cont.getContractState().equals(EContractState.NEW)) {
				respon.append("ERROR: ContractNo:")
						.append(cont.getContractNo()).append(
								"is New ,Can't Finish! ").append(" ");
				this.resultError(respon.toString(), "list");
			} else if (cont.getContractState().equals(EContractState.COMMIT)) {
				cont.setFinishTime(new Date());
				cont.setFinishUser(getSessionUser());
				cont.setContractState(EContractState.FINISHED);
				corpContractService.saveOrUpdate(cont);
				this.resultOK("finish the contract", "list");
			}
		} else {
			respon.append("ERROR: ContractNo:").append(cont.getContractNo())
					.append("hasn't state! ").append(" ");
			this.resultError(respon.toString(), "list");
		}
		fetchListData();
		return VIEW;
	}

	public String invalid() {
		StringBuffer respon = new StringBuffer();
		CorpContract cont = this.getModel();
		if (cont.getContractState() != null) {
			if (cont.getContractState().equals(EContractState.NEW)) {
				respon.append("ERROR: ContractNo:")
						.append(cont.getContractNo()).append(
								"is New ,Can't Invalid! ").append(" ");
				this.resultError(respon.toString(), "list");
			} else if (cont.getContractState().equals(EContractState.COMMIT)) {
				cont.setFinishTime(new Date());
				cont.setFinishUser(getSessionUser());
				cont.setContractState(EContractState.INVALID);
				corpContractService.saveOrUpdate(cont);
				this.resultOK("invalid the contract", "list");
			}
		} else {
			respon.append("ERROR: ContractNo:").append(cont.getContractNo())
					.append("hasn't state! ").append(" ");
			this.resultError(respon.toString(), "list");
		}
		fetchListData();
		return VIEW;
	}

	public String commit() {
		if (getSessionUser().getRole().getName().toUpperCase().equals("CC")) {
			return NONE;
		}
		CorpContract contract = this.getModel();
		if (contract.getCompany() == null) {// 新建
			contract.setContractState(EContractState.NEW);
			contract.setCreateTime(new Date());
			contract.setCreateUser(this.getSessionUser());
		}
		contract.setCompany(companyService.findById(Long.valueOf(selCompanyId
				.trim())));
		contract.setCommitTime(new Date());
		contract.setCommitUser(this.getSessionUser());
		contract.setContractState(EContractState.COMMIT);
		corpContractService.saveOrUpdate(contract);
		fetchListData();
		return VIEW;
	}

	public String delete() {
		String ids = getRequest().getParameter("ids");
		String[] id = ids.split(",");
		StringBuffer respon = new StringBuffer();
		for (String i : id) {
			CorpContract cont = corpContractService.findById(Long.valueOf(i
					.trim()));
			if (cont.getContractState().equals(EContractState.NEW)) {
				corpContractService.delete(cont);
			} else if (cont.getContractState().equals(EContractState.COMMIT)
					|| cont.getContractState().equals(EContractState.FINISHED)) {
				respon.append("ERROR: ContractNo:")
						.append(cont.getContractNo()).append(
								"is " + cont.getContractState()
										+ "  ,Can't Delete! ").append(" ");
				this.resultError(respon.toString(), "list");
			}
		}
		return DELETE;
	}

	public String view() {
		fetchListData();
		return VIEW;
	}

	public String save() {
		CorpContract contract = this.getModel();
		if (contract.getCompany() == null) {// 新建
			contract.setContractState(EContractState.NEW);
			contract.setCreateTime(new Date());
			contract.setCreateUser(this.getSessionUser());
		}
		if (contract.getStartTime().after(contract.getEndTime())) {
			this.resultError("start time mast before the end time!", "list");
			fetchListData();
			return EDIT;
		}
		contract.setCompany(companyService.findById(Long.valueOf(selCompanyId
				.trim())));
		corpContractService.saveOrUpdate(contract);
		this.setResult(ConfirmMessage.Contract);
		fetchListData();
		return EDIT;
	};

	public String export() {
		this.setStartIndex(0);
		this.setPageSize(1000);
		list();
		List<CorpContract> result = this.listResult.getItems();
		if (result.size() < 1)
			return NONE;
		HttpServletRequest request = getRequest();
		HttpServletResponse response = getResponse();

		response.setContentType("application/ms-excel;charset=UTF-8");
		response.setHeader("Content-Disposition",
				"attachment;filename=CorpContract.xls");

		File tempPath = new File(ServletActionContext.getServletContext()
				.getRealPath("/temp"));
		if (!tempPath.exists()) {
			tempPath.mkdirs();
		}
		WritableWorkbook workBook;

		File exportFile = new File(ServletActionContext.getServletContext()
				.getRealPath("/temp/CorpContract.xls"));
		try {
			// TODO styles
			WritableFont font = new WritableFont(WritableFont.TIMES, 12,
					WritableFont.BOLD);
			WritableCellFormat headStyle = new WritableCellFormat(font);
			headStyle.setAlignment(Alignment.CENTRE);
			WritableCellFormat titleStyle = new WritableCellFormat(font);
			titleStyle.setAlignment(Alignment.CENTRE);
			titleStyle.setWrap(false);
			titleStyle.setBorder(Border.ALL, BorderLineStyle.THIN);
			WritableFont font_content = new WritableFont(WritableFont.TIMES, 10);
			WritableCellFormat contentStyle = new WritableCellFormat(
					font_content);
			contentStyle.setAlignment(Alignment.CENTRE);
			contentStyle.setBorder(Border.ALL, BorderLineStyle.THIN);
			contentStyle.setWrap(false);
			workBook = Workbook.createWorkbook(exportFile);
			workBook.setProtected(false);
			// create sheets
			WritableSheet activeSheet = workBook.createSheet("sheet", 0);
			activeSheet.addCell(new Label(0, 1, "No. ", titleStyle));
			activeSheet.addCell(new Label(1, 1, "Year ", titleStyle));
			activeSheet.addCell(new Label(2, 1, "Month ", titleStyle));
			activeSheet.addCell(new Label(3, 1, "     Clent     ", titleStyle));
			activeSheet.addCell(new Label(4, 1, "Industry ", titleStyle));
			activeSheet.addCell(new Label(5, 1, "Client Type ", titleStyle));
			activeSheet
					.addCell(new Label(6, 1, "Course Category ", titleStyle));
			activeSheet.addCell(new Label(7, 1, "Material", titleStyle));
			activeSheet.addCell(new Label(8, 1, "Schedule", titleStyle));
			activeSheet.addCell(new Label(9, 1, "Location", titleStyle));
			activeSheet.addCell(new Label(10, 1, "Trainee No.", titleStyle));
			activeSheet.addCell(new Label(11, 1, "Teacher", titleStyle));
			activeSheet.addCell(new Label(12, 1, "Status", titleStyle));
			activeSheet.addCell(new Label(13, 1, "Start Day", titleStyle));
			activeSheet.addCell(new Label(14, 1, "Finish Day", titleStyle));
			activeSheet.addCell(new Label(15, 1, "Testing Fee", titleStyle));
			activeSheet.addCell(new Label(16, 1, "Transportation Fee",
					titleStyle));
			activeSheet.addCell(new Label(17, 1, "Material Fee", titleStyle));
			activeSheet.addCell(new Label(18, 1, "Training Fee", titleStyle));
			activeSheet.addCell(new Label(19, 1, "Total Contract Value",
					titleStyle));
			activeSheet.addCell(new Label(20, 1, "Payment Statement",
					titleStyle));
			activeSheet.addCell(new Label(21, 1, "CC ", titleStyle));
			activeSheet.addCell(new Label(22, 1, "Comments ", titleStyle));
			int size = result.size();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
			SimpleDateFormat sdfY = new SimpleDateFormat("yyyy");
			SimpleDateFormat sdfM = new SimpleDateFormat("MM");
			int curRowIndex = 2;
			int j = 1;
			for (CorpContract curCorp : result) {
				if (curCorp.getContractState() == null
						|| curCorp.getContractState()
								.equals(EContractState.NEW)) {
					continue;
				}
				activeSheet.addCell(new Label(0, curRowIndex, String
						.valueOf(j++), contentStyle));
				activeSheet.addCell(new Label(1, curRowIndex, sdfY
						.format(curCorp.getStartTime()), contentStyle));
				activeSheet.addCell(new Label(2, curRowIndex, sdfM
						.format(curCorp.getStartTime()), contentStyle));
				activeSheet.addCell(new Label(3, curRowIndex, curCorp
						.getCompany().getName(), contentStyle));
				activeSheet.addCell(new Label(4, curRowIndex, (curCorp
						.getCompany().getIndustry() == null ? "" : curCorp
						.getCompany().getIndustry().toString()), contentStyle));
				activeSheet
						.addCell(new Label(5, curRowIndex, (curCorp
								.getCompany().getClientType() == null ? ""
								: curCorp.getCompany().getClientType()
										.toString()), contentStyle));
				activeSheet.addCell(new Label(6, curRowIndex, (curCorp
						.getCourse() == null ? "" : curCorp.getCourse()
						.toString()), contentStyle));
				activeSheet.addCell(new Label(7, curRowIndex, "", contentStyle));
				activeSheet.addCell(new Label(8, curRowIndex,  "", contentStyle));
				activeSheet.addCell(new Label(9, curRowIndex,  "", contentStyle));
				activeSheet.addCell(new Label(10, curRowIndex,  "", contentStyle));
				activeSheet.addCell(new Label(11, curRowIndex,  "", contentStyle));
				activeSheet.addCell(new Label(12, curRowIndex, curCorp.getContractState().toString(), contentStyle));
				activeSheet.addCell(new Label(13, curRowIndex, sdf
						.format(curCorp.getStartTime()), contentStyle));
				activeSheet.addCell(new Label(14, curRowIndex, sdf
						.format(curCorp.getEndTime()), contentStyle));
				activeSheet.addCell(new Label(15, curRowIndex, (curCorp
						.getTestingFee() == null ? "" : curCorp.getTestingFee()
						.toString()), contentStyle));
				activeSheet.addCell(new Label(16, curRowIndex, (curCorp
						.getTransportationFee() == null ? "" : curCorp
						.getTransportationFee().toString()), contentStyle));
				activeSheet.addCell(new Label(17, curRowIndex, (curCorp
						.getMaterialFee() == null ? "" : curCorp
						.getMaterialFee().toString()), contentStyle));
				activeSheet.addCell(new Label(18, curRowIndex, (curCorp
						.getTrainingFee() == null ? "" : curCorp
						.getTrainingFee().toString()), contentStyle));
				activeSheet.addCell(new Label(19, curRowIndex, curCorp
						.getPrice().toString(), contentStyle));
				activeSheet.addCell(new Label(20, curRowIndex,  "", contentStyle));
				String clt = "";
				if (curCorp.getCompany().getCc() != null) {
					clt = curCorp.getCompany().getCc().getName();
				}
				activeSheet.addCell(new Label(21, curRowIndex, clt,
						contentStyle));
				activeSheet.addCell(new Label(22, curRowIndex, curCorp
						.getComments(), contentStyle));
				curRowIndex++;
			}
			workBook.write();
			workBook.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (WriteException e) {
			e.printStackTrace();
		}
		RequestDispatcher dispatcher = request
				.getRequestDispatcher("../../temp/CorpContract.xls");
		try {
			dispatcher.forward(request, response);
		} catch (ServletException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return NONE;
	}

	public Date getSelCreateStartTime() {
		return selCreateStartTime;
	}

	public void setSelCreateStartTime(Date selCreateStartTime) {
		this.selCreateStartTime = selCreateStartTime;
	}

	public Date getSelCreateEndTime() {
		return selCreateEndTime;
	}

	public void setSelCreateEndTime(Date selCreateEndTime) {
		this.selCreateEndTime = selCreateEndTime;
	}

	public Date getSelBeginStartTime() {
		return selBeginStartTime;
	}

	public void setSelBeginStartTime(Date selBeginStartTime) {
		this.selBeginStartTime = selBeginStartTime;
	}

	public Date getSelBeginEndTime() {
		return selBeginEndTime;
	}

	public void setSelBeginEndTime(Date selBeginEndTime) {
		this.selBeginEndTime = selBeginEndTime;
	}

	public Date getSelEndStartTime() {
		return selEndStartTime;
	}

	public void setSelEndStartTime(Date selEndStartTime) {
		this.selEndStartTime = selEndStartTime;
	}

	public Date getSelEndEndTime() {
		return selEndEndTime;
	}

	public void setSelEndEndTime(Date selEndEndTime) {
		this.selEndEndTime = selEndEndTime;
	}

	public Date getSelCommitStartTime() {
		return selCommitStartTime;
	}

	public void setSelCommitStartTime(Date selCommitStartTime) {
		this.selCommitStartTime = selCommitStartTime;
	}

	public Date getSelCommitEndTime() {
		return selCommitEndTime;
	}

	public void setSelCommitEndTime(Date selCommitEndTime) {
		this.selCommitEndTime = selCommitEndTime;
	}

	public Date getSelFinishStartTime() {
		return selFinishStartTime;
	}

	public void setSelFinishStartTime(Date selFinishStartTime) {
		this.selFinishStartTime = selFinishStartTime;
	}

	public Date getSelFinishEndTime() {
		return selFinishEndTime;
	}

	public void setSelFinishEndTime(Date selFinishEndTime) {
		this.selFinishEndTime = selFinishEndTime;
	}

	public CorpContractService getCorpContractService() {
		return corpContractService;
	}

	public void setCorpContractService(CorpContractService corpContractService) {
		this.corpContractService = corpContractService;
	}

	public CompanyService getCompanyService() {
		return companyService;
	}

	public void setCompanyService(CompanyService companyService) {
		this.companyService = companyService;
	}

	public String getSelCompanyId() {
		return selCompanyId;
	}

	public void setSelCompanyId(String selCompanyId) {
		this.selCompanyId = selCompanyId;
	}

	public List<CorpPayHistory> getCorpPayHistoryList() {
		return corpPayHistoryList;
	}

	public void setCorpPayHistoryList(List<CorpPayHistory> corpPayHistoryList) {
		this.corpPayHistoryList = corpPayHistoryList;
	}

	public CorpPayService getCorpPayService() {
		return corpPayService;
	}

	public void setCorpPayService(CorpPayService corpPayService) {
		this.corpPayService = corpPayService;
	}

	public String getSelCompanyName() {
		return selCompanyName;
	}

	public void setSelCompanyName(String selCompanyName) {
		this.selCompanyName = selCompanyName;
	}

	public CorpClassService getCorpClassService() {
		return corpClassService;
	}

	public void setCorpClassService(CorpClassService corpClassService) {
		this.corpClassService = corpClassService;
	}

	public List<CorpClass> getCorpClassList() {
		return corpClassList;
	}

	public void setCorpClassList(List<CorpClass> corpClassList) {
		this.corpClassList = corpClassList;
	}
}
